﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using eCommerce.Core.Data;
using eCommerce.Core.Domain.Addresses;
using eCommerce.Core.Domain.Brands;
using eCommerce.Core.Domain.Categorys;
using eCommerce.Core.Domain.Customers;
using eCommerce.Core.Domain.Messges;
using eCommerce.Core.Domain.Products;
using eCommerce.Core.Domain.Securitys;
using eCommerce.Core.Domain.Shops;
using eCommerce.Services.Security;

namespace eCommerce.Services.Installations
{
    public class InstallService : IInstallService
    {

        private IRepository<Product> _productRep;
        private IRepository<Item> _itemRep;
        private IRepository<ItemGroup> _itemGroupRep;
        private IRepository<ItemAttributeKey> _itemAttributeKeyRep;
        private IRepository<ProductAttributeKey> _productAttributeKeyRep;
        private IRepository<Address> _addressRep;
        private IRepository<Message> _messageRep;
        private IRepository<Customer> _customerRep;
        private IRepository<CustomerRole> _customerRoleRep;
        private IRepository<Shop> _shopRep;
        private IRepository<Category> _categoryRep;
        private IRepository<Brand> _brandRep;
        private IEncryptionService _encryptionService;

        public InstallService(IRepository<Message> messageRep, IRepository<Customer> customerRep, IEncryptionService encryptionService, IRepository<Address> addressRep, IRepository<CustomerRole> customerRoleRep, IRepository<Shop> shopRep, IRepository<Category> categoryRep, IRepository<ProductAttributeKey> productAttributeKeyRep, IRepository<ItemAttributeKey> itemAttributeKeyRep, IRepository<Brand> brandRep, IRepository<Item> itemRep, IRepository<Product> productRep, IRepository<ItemGroup> itemGroupRep)
        {
            _messageRep = messageRep;
            _customerRep = customerRep;
            _encryptionService = encryptionService;
            _addressRep = addressRep;
            _customerRoleRep = customerRoleRep;
            _shopRep = shopRep;
            _categoryRep = categoryRep;
            _productAttributeKeyRep = productAttributeKeyRep;
            _itemAttributeKeyRep = itemAttributeKeyRep;
            _brandRep = brandRep;
            _itemRep = itemRep;
            _productRep = productRep;
            _itemGroupRep = itemGroupRep;
        }


        private void InstallAttributes()
        {
            var msg = _productAttributeKeyRep.Table.ToList();
            foreach (var message in msg)
            {
                _productAttributeKeyRep.Delete(message);
            }

            var msg2 = _itemAttributeKeyRep.Table.ToList();
            foreach (var message in msg2)
            {
                _itemAttributeKeyRep.Delete(message);
            }

            var cats = _categoryRep.Table.ToList();

            foreach (var cat in cats)
            {
                var pA = new ProductAttributeKey()
                {
                    IsEmpty = true,
                    CategoryId = cat.Id,
                };
                _productAttributeKeyRep.Insert(pA);

                var iA = new ItemAttributeKey()
                {
                    Id = -1,
                    IsEmpty = true,
                    CategoryId = cat.Id,
                };
                _itemAttributeKeyRep.Insert(iA);

                var productAttributeKey = new ProductAttributeKey()
                {
                    CategoryId = cat.Id,
                    Name = "color",
                };

                var itemAttributeKey = new ItemAttributeKey()
                {
                    CategoryId = cat.Id,
                    Name = "size"
                };


                _productAttributeKeyRep.Insert(productAttributeKey);
                _itemAttributeKeyRep.Insert(itemAttributeKey);
            }

        }

        private void InstallMessage()
        {
            var msg = _messageRep.Table.ToList();
            foreach (var message in msg)
            {
                _messageRep.Delete(message);
            }


            var m = new Message()
            {
                ResourceName = MessageName.RemoveProductAttributeKeyName,
                ResourceValue = "remove"
            };

            _messageRep.Insert(m);
            m = new Message()
            {
                ResourceName = MessageName.AddProductAttributeKeyName,
                ResourceValue = "add"
            };

            _messageRep.Insert(m);


            m = new Message()
            {
                ResourceName = MessageName.InsertProduct,
                ResourceValue = "save"
            };
            _messageRep.Insert(m);

            m = new Message()
            {
                ResourceName = MessageName.CustomerRegistrationService_ValidateCustomer_LoginSuccess,
                ResourceValue = "login success"
            };
            _messageRep.Insert(m);

            m = new Message()
            {
                ResourceName = MessageName.CustomerRegistrationService_ValidateCustomer_LoginFailed,
                ResourceValue = "login failed"
            };
            _messageRep.Insert(m);
            m = new Message()
            {
                ResourceName = MessageName.InsertItem,
                ResourceValue = "save"
            };
            _messageRep.Insert(m);
            m = new Message()
            {
                ResourceName = MessageName.AddToCart,
                ResourceValue = "Add to Cart"
            };


           
            _messageRep.Insert(m);


             m = new Message()
            {
                ResourceName = MessageName.ItemNotExist,
                ResourceValue = "item not exist"
            };

           
            _messageRep.Insert(m);
             
        }


        private int InstallCustomers()
        {
            var datas= _customerRep.Table.ToList();
            foreach (var data in datas)
            {
                _customerRep.Delete(data);
            }


            var customer = new Customer()
            {
                Active = true,
                Username = "zhuzhu",
                Password = _encryptionService.CreatePasswordHash("123456", "aabbcc", "SHA1"),
                Email = "ee@ee.com",
                UserGuid = Guid.NewGuid(),
                Deleted = false,
                CreatedOn = DateTime.Now
            };
            var defaultAddress = new Address()
            {
                FirstName = "Mike",
                LastName = "Yi",
                PhoneNumber = "12345678",
                MobileNumber = "1232323",
                Email = "ee@ee.com",
                Province = "shang hai", 
                Address1 = "21 West 52nd Street",
                Address2 = "",
                City = "New York",
                ZipPostalCode = "10021",
                CreatedOn = DateTime.UtcNow,
            };

            _addressRep.Insert(defaultAddress);

            var registedRole = _customerRoleRep.Table.Where(c => c.SystemName == "Registered").FirstOrDefault();

            customer.CustomerRoles.Add(registedRole);
            customer.ShippingAddress = defaultAddress;

            customer.Addresses.Add(defaultAddress);
            _customerRep.Insert(customer);
            return customer.Id;
        }

        private int InstallShopOwner()
        {
            var customer = new Customer()
            {
                Active = true,
                Username = "shopowner",
                Password = _encryptionService.CreatePasswordHash("123456", "aabbcc", "SHA1"),
                Email = "cc@cc.com",
                UserGuid = Guid.NewGuid(),
                Deleted = false,
                CreatedOn = DateTime.Now
            };
            var defaultAddress = new Address()
            {
                FirstName = "John",
                LastName = "Smith",
                PhoneNumber = "12345678",
                MobileNumber = "1232323",
                Email = "admin@yourStore.com",
                Province = "shang hai",
                Address1 = "21 West 52nd Street",
                Address2 = "",
                City = "New York",
                ZipPostalCode = "10021",
                CreatedOn = DateTime.UtcNow,
            };

            _addressRep.Insert(defaultAddress);

            var shopOwerRole = _customerRoleRep.Table.Where(c => c.SystemName == "ShopOwner").FirstOrDefault();
            var registedRole = _customerRoleRep.Table.Where(c => c.SystemName == "Registered").FirstOrDefault();

            customer.CustomerRoles.Add(shopOwerRole);
            customer.CustomerRoles.Add(registedRole);
            customer.ShippingAddress = defaultAddress;

            customer.Addresses.Add(defaultAddress);
            _customerRep.Insert(customer);
            return customer.Id;
        }

        private void InstallShop(int shopOwnerId)
        {
            var datas = _shopRep.Table.ToList();
            foreach (var data in datas)
            {
                _shopRep.Delete(data);
            }

            var shop = new Shop()
            {
                ShopName = "hello world",
                CustomerId = shopOwnerId
            };
            _shopRep.Insert(shop);

            var customer = _customerRep.GetById(shopOwnerId);
            customer.ShopId = shop.Id;
            _customerRep.Update(customer);

          
        }

        private void InstallPermissionRecordRoleMapping()
        {


            var manageProduct = new PermissionRecord()
            {
                SystemName = "ManageProduct"

            };


            var manageOrders = new PermissionRecord()
            {
                SystemName = "ManageOrders"

            };

            var accessAdmin = new PermissionRecord()
            {
                SystemName = "AccessAdmin"

            };

            var manageCustomer = new PermissionRecord()
            {
                SystemName = "ManageCustomers"

            };


            var manageShipping = new PermissionRecord()
            {
                SystemName = "ManageShipping"

            };


            var manageShop = new PermissionRecord()
            {
                SystemName = "ManageShop"

            };



            var administrator = new CustomerRole()
            {
                Active = true,
                SystemName = "Administrators",
                PermissionRecords = new Collection<PermissionRecord>()
                {
                    manageProduct,
                    manageOrders,
                    accessAdmin,
                    manageCustomer,
                    manageShipping,
                    manageShop
                }
            };
            _customerRoleRep.Insert(administrator);

            var shopowner = new CustomerRole()
            {
                Active = true,
                SystemName = "ShopOwner",

                PermissionRecords = new Collection<PermissionRecord>()
                {
                    manageProduct,
                    manageOrders,
                    accessAdmin,
                    manageShipping,
                }
            };
            _customerRoleRep.Insert(shopowner);


            var role = new CustomerRole()
            {
                Active = true,
                SystemName = "Guests"
            };
            _customerRoleRep.Insert(role);

            role = new CustomerRole()
            {
                Active = true,
                SystemName = "Registered"
            };
            _customerRoleRep.Insert(role);

        }

   
        public void Install()
        {
            InstallPermissionRecordRoleMapping();
            DeleteItems();
            DeleteItemGroups();
            DeleteProducts();
            InstallCategory();

            IntallBrand();
            InstallMessage();
            InstallCustomers();

            var shopOwnerId= InstallShopOwner();
            InstallShop(shopOwnerId);


            InstallAttributes();

        }

        private void DeleteItemGroups()
        {
            var datas = _itemGroupRep.Table.ToList();
            foreach (var data in datas)
            {
                _itemGroupRep.Delete(data);
            }
        }

        private void DeleteProducts()
        {
            var datas = _productRep.Table.ToList();
            foreach (var data in datas)
            {
                _productRep.Delete(data);
            }
        }

        private void DeleteItems()
        {
            var datas = _itemRep.Table.ToList();
            foreach (var data in datas)
            {
                _itemRep.Delete(data);
            }
        }

        private void IntallBrand()
        {
            var datas = _brandRep.Table.ToList();
            foreach (var data in datas)
            {
                _brandRep.Delete(data);
            }
            var b = new Brand()
            {
                Name = "default",
                CreatedOnUtc = DateTime.Now,
                UpdatedOnUtc = DateTime.Now,

            };
            _brandRep.Insert(b);
        }

        private void InstallCategory()
        {
            var datas = _categoryRep.Table.ToList();
            foreach (var data in datas)
            {
                _categoryRep.Delete(data);
            }


            var datas2 = _productAttributeKeyRep.Table.ToList();
            foreach (var data in datas2)
            {
                _productAttributeKeyRep.Delete(data);
            }

            var datas3 = _itemAttributeKeyRep.Table.ToList();
            foreach (var data in datas3)
            {
                _itemAttributeKeyRep.Delete(data);
            }

            var cat = new Category()
            {
                Name = "default",
                CreatedOnUtc = DateTime.Now,
                UpdatedOnUtc = DateTime.Now,

            };
            _categoryRep.Insert(cat);


           
        }
    }
}